import mqtt from 'mqtt';
import CryptoJS from 'crypto-js';
import { ref } from 'vue';

// MQTT QoS类型
type QoS = 0 | 1 | 2;

// MQTT连接状态
export const connectionStatus = ref<'disconnected' | 'connecting' | 'connected'>('disconnected');
export const lastError = ref<string | null>(null);
export const lastRfidMessage = ref<string | null>(null);
export const debugInfo = ref<string[]>([]);
export const lastPingTime = ref<number>(0);
export const pingInterval = ref<number>(0);

// 阿里云IoT参数
const productKey = 'iwgqDwr0Ag2';
const deviceName = 'vue3';
const deviceSecret = '8f63b3496b796dde00b7258950b71aca';
const mqttHostUrl = 'iot-06z00bmdast8kax.mqtt.iothub.aliyuncs.com';
const port = 1883;

// 订阅的主题
const topics = [
  `/sys/${productKey}/${deviceName}/thing/event/property/post`,
  `/sys/${productKey}/${deviceName}/thing/service/property/set`
];

// 心跳主题
const pingTopic = `/sys/${productKey}/${deviceName}/ping`;

// MQTT客户端实例
let client: mqtt.MqttClient | null = null;
let heartbeatTimer: number | null = null;
let reconnectTimer: number | null = null;
let reconnectAttempts = 0;
const maxReconnectAttempts = 10;
const reconnectDelay = 5000; // 初始重连延迟5秒

// 添加调试日志
function addDebugLog(message: string) {
  console.log(message);
  debugInfo.value.push(`${new Date().toLocaleTimeString()}: ${message}`);
  // 只保留最近20条日志
  if (debugInfo.value.length > 20) {
    debugInfo.value.shift();
  }
}

// 生成阿里云IoT MQTT连接参数
function generateAliyunIoTParams() {
  const timestamp = Date.now();
  const clientId = `${productKey}.${deviceName}|securemode=2,signmethod=hmacsha256,timestamp=${timestamp}|`;
  const username = `${deviceName}&${productKey}`;
  
  // 构建签名所需的参数映射
  const params: Record<string, string> = {
    'productKey': productKey,
    'deviceName': deviceName,
    'clientId': `${productKey}.${deviceName}`,
    'timestamp': timestamp.toString()
  };
  
  // 按字典顺序排序参数
  const keys = Object.keys(params).sort();
  
  // 构建待签名字符串
  let signContent = '';
  keys.forEach(key => {
    signContent += key + params[key];
  });
  
  // 使用HMAC-SHA256算法和设备密钥对signContent进行加密
  const hmac = CryptoJS.HmacSHA256(signContent, deviceSecret);
  const password = CryptoJS.enc.Hex.stringify(hmac);
  
  return { clientId, username, password, timestamp };
}

// 发送心跳包
function sendHeartbeat() {
  if (client && client.connected) {
    const message = {
      id: Date.now(),
      params: {
        status: 'online'
      }
    };
    
    client.publish(pingTopic, JSON.stringify(message), { qos: 1 as QoS });
    lastPingTime.value = Date.now();
    addDebugLog(`发送心跳包: ${JSON.stringify(message)}`);
  }
}

// 启动心跳机制
function startHeartbeat() {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
  }
  
  // 每30秒发送一次心跳包
  heartbeatTimer = window.setInterval(() => {
    sendHeartbeat();
  }, 30000) as unknown as number;
  
  // 立即发送一次心跳包
  sendHeartbeat();
}

// 停止心跳机制
function stopHeartbeat() {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  }
}

// 启动重连机制
function startReconnect(onRfidReceived: (rfidId: string) => void) {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
  }
  
  // 指数退避重连
  const delay = Math.min(reconnectDelay * Math.pow(2, reconnectAttempts), 60000); // 最大60秒
  
  reconnectTimer = window.setTimeout(() => {
    if (reconnectAttempts < maxReconnectAttempts) {
      addDebugLog(`尝试重新连接 (${reconnectAttempts + 1}/${maxReconnectAttempts})...`);
      connectMqtt(onRfidReceived, true);
      reconnectAttempts++;
    } else {
      addDebugLog(`已达到最大重连次数 (${maxReconnectAttempts})，停止重连`);
      connectionStatus.value = 'disconnected';
      lastError.value = '已达到最大重连次数，请手动重新连接';
    }
  }, delay) as unknown as number;
  
  addDebugLog(`将在 ${delay/1000} 秒后重新连接`);
}

// 停止重连机制
function stopReconnect() {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
  reconnectAttempts = 0;
}

// 连接MQTT服务器
export function connectMqtt(onRfidReceived: (rfidId: string) => void, isReconnect = false) {
  if (client && !isReconnect) {
    addDebugLog('MQTT客户端已存在，断开重连');
    disconnectMqtt();
  }
  
  connectionStatus.value = 'connecting';
  if (!isReconnect) {
    lastError.value = null;
    debugInfo.value = [];
    reconnectAttempts = 0;
  }
  
  try {
    // 生成最新的连接参数
    const { clientId, username, password } = generateAliyunIoTParams();
    
    addDebugLog('使用动态生成的参数连接MQTT');
    addDebugLog(`clientId: ${clientId}`);
    addDebugLog(`username: ${username}`);
    
    // 使用安全WebSocket连接
    const connectUrl = `wss://${mqttHostUrl}/mqtt`;
    
    const mqttOptions = {
      clientId,
      username,
      password,
      clean: true,
      reconnectPeriod: 0, // 禁用内置重连，使用自定义重连机制
      connectTimeout: 30 * 1000,
      keepalive: 60, // 60秒keepalive
      will: { // 遗嘱消息，当客户端异常断开时发送
        topic: `/sys/${productKey}/${deviceName}/thing/event/property/post`,
        payload: JSON.stringify({
          id: Date.now(),
          params: {
            status: 'offline'
          },
          version: "1.0",
          method: "thing.event.property.post"
        }),
        qos: 1 as QoS,
        retain: false
      }
    };
    
    addDebugLog('开始连接MQTT...');
    stopReconnect(); // 停止之前的重连
    client = mqtt.connect(connectUrl, mqttOptions);
    
    client.on('connect', () => {
      connectionStatus.value = 'connected';
      addDebugLog('MQTT连接成功');
      reconnectAttempts = 0; // 重置重连次数
      
      // 订阅多个主题
      topics.forEach(topic => {
        client?.subscribe(topic, { qos: 1 as QoS }, (err) => {
          if (err) {
            addDebugLog(`订阅主题失败: ${topic} - ${err.message}`);
            lastError.value = `订阅失败: ${err.message}`;
          } else {
            addDebugLog(`成功订阅主题: ${topic}`);
          }
        });
      });
      
      // 启动心跳机制
      startHeartbeat();
    });
    
    client.on('message', (topic, payload) => {
      const message = payload.toString();
      addDebugLog(`收到MQTT消息: ${topic}, ${message}`);
      try {
        const parsedMessage = JSON.parse(message);
        
        // 处理不同格式的MQTT消息
        if (topic === `/sys/${productKey}/${deviceName}/thing/service/property/set`) {
          // 处理属性设置消息
          if (parsedMessage.items && parsedMessage.items.RFID_ID && parsedMessage.items.RFID_ID.value) {
            const rfidId = parsedMessage.items.RFID_ID.value;
            lastRfidMessage.value = rfidId;
            addDebugLog(`从属性设置消息中提取RFID ID: ${rfidId}`);
            onRfidReceived(rfidId);
          }
        } else if (parsedMessage.params && parsedMessage.params.RFID_ID) {
          // 处理属性上报消息
          const rfidId = parsedMessage.params.RFID_ID;
          lastRfidMessage.value = rfidId;
          addDebugLog(`从属性上报消息中提取RFID ID: ${rfidId}`);
          onRfidReceived(rfidId);
        }
      } catch (error: any) {
        addDebugLog(`解析MQTT消息失败: ${error.message}`);
      }
    });
    
    client.on('error', (err) => {
      addDebugLog(`MQTT连接错误: ${err.message}`);
      lastError.value = `连接错误: ${err.message}`;
    });
    
    client.on('close', () => {
      addDebugLog('MQTT连接已关闭');
      connectionStatus.value = 'disconnected';
      stopHeartbeat();
      
      // 启动重连机制
      startReconnect(onRfidReceived);
    });
    
    client.on('offline', () => {
      addDebugLog('MQTT客户端离线');
      connectionStatus.value = 'disconnected';
      stopHeartbeat();
      
      // 启动重连机制
      startReconnect(onRfidReceived);
    });
    
    client.on('reconnect', () => {
      addDebugLog('MQTT客户端内部重连中');
      connectionStatus.value = 'connecting';
    });
    
    // 添加连接超时处理
    setTimeout(() => {
      if (connectionStatus.value === 'connecting') {
        addDebugLog('MQTT连接超时');
        lastError.value = '连接超时，请检查网络和配置';
        
        // 启动重连机制
        if (!isReconnect) {
          startReconnect(onRfidReceived);
        }
      }
    }, 15000);
    
  } catch (error: any) {
    addDebugLog(`MQTT连接初始化错误: ${error.message}`);
    lastError.value = `初始化错误: ${error.message}`;
    connectionStatus.value = 'disconnected';
    
    // 启动重连机制
    if (!isReconnect) {
      startReconnect(onRfidReceived);
    }
  }
}

// 断开MQTT连接
export function disconnectMqtt() {
  stopHeartbeat();
  stopReconnect();
  
  if (client) {
    // 发送离线状态
    try {
      if (client.connected) {
        const message = {
          id: Date.now(),
          params: {
            status: 'offline'
          },
          version: "1.0",
          method: "thing.event.property.post"
        };
        
        client.publish(`/sys/${productKey}/${deviceName}/thing/event/property/post`, 
          JSON.stringify(message), { qos: 1 as QoS }, () => {
            client?.end(true);
          });
        
        addDebugLog('已发送离线状态');
      } else {
        client.end(true);
      }
    } catch (error) {
      client.end(true);
    }
    
    client = null;
    connectionStatus.value = 'disconnected';
    addDebugLog('MQTT连接已断开');
  }
}

// 模拟发送RFID消息（用于测试）
export function simulateMqttMessage(rfidId: string) {
  const topic = `/sys/${productKey}/${deviceName}/thing/event/property/post`;
  const message = {
    id: Date.now(),
    params: {
      RFID_ID: rfidId
    },
    version: "1.0",
    method: "thing.event.property.post"
  };
  
  if (client && client.connected) {
    client.publish(topic, JSON.stringify(message), { qos: 1 as QoS });
    addDebugLog(`已发送模拟MQTT消息: ${JSON.stringify(message)}`);
    return true;
  } else {
    addDebugLog('MQTT客户端未连接，无法发送消息');
    return false;
  }
}

// 检查MQTT连接状态
export function checkMqttConnection(onRfidReceived: (rfidId: string) => void) {
  if (!client || !client.connected) {
    addDebugLog('MQTT连接已断开，尝试重新连接');
    connectMqtt(onRfidReceived);
    return false;
  }
  
  // 检查最后一次心跳时间
  const now = Date.now();
  const lastPing = lastPingTime.value;
  
  // 如果超过2分钟没有心跳，认为连接已断开
  if (lastPing > 0 && now - lastPing > 120000) {
    addDebugLog('MQTT心跳超时，尝试重新连接');
    disconnectMqtt();
    connectMqtt(onRfidReceived);
    return false;
  }
  
  return true;
} 